package com.easycms.framework.configs;
import com.easycms.framework.shiro.EasyLogoutFilter;
import com.easycms.framework.shiro.realm.TokenRealm;
import com.easycms.framework.shiro.stateless.StatelessAuthcFilter;
import com.easycms.framework.shiro.stateless.StatelessWebSubjectFactory;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.*;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author yushuo
 * @className
 * @descripton TODO
 * @date 2021/2/4 16:11
 **/
@Configuration
public class ShiroConfig {


    /**
     * 退出过滤器
     */
    public EasyLogoutFilter logoutFilter() {
        EasyLogoutFilter logoutFilter = new EasyLogoutFilter();
        logoutFilter.setLoginUrl("/login");
        return logoutFilter;
    }



    /**
    *
     * @author yushuo
     * @description shiroRealm 将自己的验证方式加入容器
     * @date 11:21 2021/2/22
     * @param []
     * @return com.easycms.framework.shiro.realm.TokenRealm
    **/
    @Bean
    public TokenRealm shiroRealm() {
        TokenRealm tokenRealm = new TokenRealm();
        tokenRealm.setCachingEnabled(false);
        return tokenRealm;
    }


    /**
    *
     * @author yushuo
     * @description //去除url加上的JSESSIONID
     * @date 10:15 2021/2/8
     * @param []
     * @return org.apache.shiro.web.session.mgt.DefaultWebSessionManager
    **/
    @Bean
    public DefaultWebSecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 禁用sessionStorage
        ((DefaultSessionStorageEvaluator) ((DefaultSubjectDAO) securityManager.getSubjectDAO())
                .getSessionStorageEvaluator()).setSessionStorageEnabled(false);
        // 禁用session会话调度器
        DefaultSessionManager sessionManager = new DefaultSessionManager();
        sessionManager.setSessionValidationSchedulerEnabled(false);
        securityManager.setSessionManager(sessionManager);
        // 禁止创建session
        securityManager.setSubjectFactory(new StatelessWebSubjectFactory());
        // 设置认证和授权服务
        securityManager.setRealm(shiroRealm());
        // 设置SecurityUtils的静态方法 获取用户等使用 SecurityManager
        SecurityUtils.setSecurityManager(securityManager);
        return securityManager;

    }

    /**
    *
     * @author yushuo
     * @description Filter工厂，设置对应的过滤条件和跳转条件
     * @date 16:36 2021/2/7
     * @param [securityManager]
     * @return org.apache.shiro.spring.web.ShiroFilterFactoryBean
    **/
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //自定义过滤器
        Map<String, Filter> filters = new LinkedHashMap<String, Filter>();
        // 注销成功，则跳转到指定页面过滤器
        // filters.put("logout", logoutFilter());
        filters.put("token", new StatelessAuthcFilter());
        shiroFilterFactoryBean.setFilters(filters);
        //url过滤设置
        Map<String, String> allowedMap = new LinkedHashMap<>();
        // 对静态资源设置匿名访问
        allowedMap.put("/favicon.ico", "anon");
        allowedMap.put("/ui/**", "anon");
        allowedMap.put("/ui/fonts/**", "anon");
        allowedMap.put("/captcha/captchaImage**", "anon");
        //登出 实现logoutfilter无需在controller层面实现
        allowedMap.put("/logout", "anon");
        //登出 实现logoutfilter无需在controller层面实现
        allowedMap.put("/login", "anon");
        //登录
        allowedMap.put("/loginOn", "anon");
        //对所有用户认证 设置顺序不能错，这个必须在最下面
        allowedMap.put("/**", "token");
        //登录
        shiroFilterFactoryBean.setLoginUrl("/login");
        //首页
        shiroFilterFactoryBean.setSuccessUrl("/home/index");
        //错误页面，认证不通过跳转
        shiroFilterFactoryBean.setUnauthorizedUrl("/error/unauth");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(allowedMap);


        return shiroFilterFactoryBean;
    }


    /**
     * 开启注解
     *
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }


}
